﻿using System;
using System.Collections.Generic;
using System.ServiceModel.Description;


namespace advadev.DataStorage
{

    /// <summary>
    /// Abstract base class of all data storage services
    /// </summary>
    abstract public class DataStorageService : IDataStorageService
    {

        /// <summary>
        /// Initializes a new instance of the DataStorageService class by the
        /// given parameter
        /// </summary>
        /// <param name="genericEntityDataStorage">
        /// Generic entity data storage
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Will be thrown if the generic entity data storage is null
        /// </exception>
        protected DataStorageService(IGenericEntityDataStorage genericEntityDataStorage)
        {
            if (genericEntityDataStorage == null)
            {
                throw new ArgumentNullException("genericEntityDataStorage");
            }
            GenericEntityDataStorage = genericEntityDataStorage;
        }


        /// <summary>
        /// When implemented, gets the service administrator credentials (or
        /// null)
        /// </summary>
        /// <remarks>
        /// If this is null everyone can call the "FindApplicationKeys"-
        /// method
        /// </remarks>
        abstract protected ClientCredentials ServiceAdministratorCredentials
        {
            get;
        }

        /// <summary>
        /// Gets or sets the generic entity data storage
        /// </summary>
        private IGenericEntityDataStorage GenericEntityDataStorage
        {
            get;
            set;
        }


        #region IDataStorageService implementation
        /// <summary>
        /// Saves the given generic entity
        /// </summary>
        /// <param name="genericEntity">
        /// Generic entity to save
        /// </param>
        public void Save(GenericEntity genericEntity)
        {
            GenericEntityDataStorage.Save(genericEntity);
        }

        /// <summary>
        /// Saves the given list of generic entities
        /// </summary>
        /// <param name="genericEntities">
        /// List of generic entities to save
        /// </param>
        public void Save(IList<GenericEntity> genericEntities)
        {
            GenericEntityDataStorage.Save(genericEntities);
        }

        /// <summary>
        /// Finds the generic entity with the given id, application key and type
        /// </summary>
        /// <param name="id">
        /// Id of the generic entity
        /// </param>
        /// <param name="applicationKey">
        /// Application key
        /// </param>
        /// <param name="fullClassName">
        /// Full class name of the type
        /// </param>
        /// <returns>
        /// The generic entity or null
        /// </returns>
        public GenericEntity Find(string id, string applicationKey, string fullClassName)
        {
            return GenericEntityDataStorage.Find(id, applicationKey, fullClassName);
        }

        /// <summary>
        /// Selects all generic entities with the given application key and type
        /// </summary>
        /// <param name="applicationKey">
        /// Application key
        /// </param>
        /// <param name="fullClassName">
        /// Full class name of the type
        /// </param>
        /// <returns>
        /// A list of generic entities
        /// </returns>
        public IList<GenericEntity> Select(string applicationKey, string fullClassName)
        {
            return GenericEntityDataStorage.Select(applicationKey, fullClassName);
        }

        /// <summary>
        /// Deletes the given generic entity
        /// </summary>
        /// <param name="genericEntity">
        /// Generic entity to delete
        /// </param>
        public void Delete(GenericEntity genericEntity)
        {
            GenericEntityDataStorage.Delete(genericEntity);
        }

        /// <summary>
        /// Deletes the given list of generic entities
        /// </summary>
        /// <param name="genericEntities">
        /// List of generic entities to delete
        /// </param>
        public void Delete(IList<GenericEntity> genericEntities)
        {
            GenericEntityDataStorage.Delete(genericEntities);
        }

        /// <summary>
        /// Deletes all generic entities with the given application key and type
        /// </summary>
        /// <param name="applicationKey">
        /// Application key
        /// </param>
        /// <param name="fullClassName">
        /// Full class name of the type
        /// </param>
        public void Delete(string applicationKey, string fullClassName)
        {
            GenericEntityDataStorage.Delete(applicationKey, fullClassName);
        }

        /// <summary>
        /// Deletes all generic entities with the given application key
        /// </summary>
        /// <param name="applicationKey">
        /// Application key
        /// </param>
        public void Delete(string applicationKey)
        {
            GenericEntityDataStorage.Delete(applicationKey);
        }

        /// <summary>
        /// Finds all full class names with the given application key
        /// </summary>
        /// <param name="applicationKey">
        /// Application key
        /// </param>
        /// <returns>
        /// List of full class names or empty list
        /// </returns>
        public IList<string> FindFullClassNames(string applicationKey)
        {
            return GenericEntityDataStorage.FindFullClassNames(applicationKey);
        }

        /// <summary>
        /// Finds all application keys
        /// </summary>
        /// <param name="administratorCredentials">
        /// Administrator credentials
        /// </param>
        /// <returns>
        /// List of application keys or empty list
        /// </returns>
        public IList<string> FindApplicationKeys(ClientCredentials administratorCredentials)
        {
            if (administratorCredentials == null || administratorCredentials.UserName == null)
            {
                return new List<string>();
            }
            string administratorUserName = (ServiceAdministratorCredentials != null && ServiceAdministratorCredentials.UserName != null ? ServiceAdministratorCredentials.UserName.UserName : null);
            string administratorPassword = (ServiceAdministratorCredentials != null && ServiceAdministratorCredentials.UserName != null ? ServiceAdministratorCredentials.UserName.Password : null);
            if (administratorCredentials.UserName.UserName == administratorUserName && administratorCredentials.UserName.Password == administratorPassword)
            {
                return GenericEntityDataStorage.FindApplicationKeys();
            }
            return new List<string>();
        }
        #endregion IDataStorageService implementation

    }

}
